package cn.hyh.core.service.impl;

import cn.hyh.core.component.CanTellUserException;
import cn.hyh.core.dao.ExperienceMapper;
import cn.hyh.core.dao.UserInfoMapper;
import cn.hyh.core.dao.UserMapper;
import cn.hyh.core.dao.VisitHistoryMapper;
import cn.hyh.core.pojo.Experience;
import cn.hyh.core.pojo.User;
import cn.hyh.core.pojo.UserInfo;
import cn.hyh.core.pojo.VisitHistory;
import cn.hyh.core.service.ServiceInterface.UserService;
import cn.hyh.core.util.DateUtils;
import cn.hyh.core.util.HttpUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.PathParam;
import java.util.*;

/**
 * @auther :hyh
 * @desc :
 * @date :2019/7/11
 */
@Service
public class UserServiceImpl  implements UserService  {

    @Value("${blog.author}")
    private String author;
    @Resource
    private AsyncServiceImpl asyncServiceImpl;

    @Resource
    private UserMapper userMapper;

    @Resource
    private VisitHistoryMapper visitHistoryMapper;

    @Resource
    private UserInfoMapper UserInfoMapper;

    @Resource
    private ExperienceMapper experienceMapper;


    public User getUserInfo(String i) {
        User user = userMapper.selectById(Long.parseLong(i));
        return  user;
    }


    @Override
    public UserInfo getUserInfo() {
        /**
         * 根据yml 中定义的名称来查询
         */
        List<UserInfo> infos = UserInfoMapper.selectList(new QueryWrapper<UserInfo>().eq("name", author));
        if (infos == null || infos.size() == 0) {
            throw new CanTellUserException("查找不到数据!");
        }
        return infos.get(0);
    }

    /**
     * 根据请求获取对应的ip
     * @param request
     * @return
     */
    @Override
    public int getVisitorAddress(HttpServletRequest request) {
            //获取ip

        String realIp = HttpUtils.getRealIp(request);
        VisitHistory  lasest=visitHistoryMapper.findLasestHistory(realIp);
        int  count =0;
        if (lasest == null) {
              //从来没有访问。
            count = visitHistoryMapper.selectCount(null)+1;
            asyncServiceImpl.saveHistory(realIp);
            System.out.println("11111");

        }else {
            Date time = lasest.getCreateTime();
            if (!DateUtils.isCompareDays(time, 0)) {
                //说明是不同一天。
                count = visitHistoryMapper.selectCount(null)+1;
                asyncServiceImpl.saveHistory(realIp);
                System.out.println("33333");
            }

        }
        return count;
    }

    /**
     *   管理员登录
     * @param username
     * @param password
     * @return
     */
    @Override
    public Map<String, Object> login(String username, String password) {
         //shiro登录
        byte[] bytes = Base64.decodeBase64(password);
        String pwd = new String(bytes);
        UsernamePasswordToken token = new UsernamePasswordToken("a"+username, pwd);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            User  currentUser= (User) subject.getPrincipal();
            if (subject.isAuthenticated()) {
                Map<String, Object> map = new HashMap<>();
                currentUser.setPassword(null);
                map.put("currentUser", currentUser);
                return map;
            }else {
                throw new CanTellUserException("登录失败!");
            }
        }catch (UnknownAccountException e){
            throw new CanTellUserException("用户名或密码错误!");
        }catch (IncorrectCredentialsException e){
            throw new CanTellUserException("用户名或密码错误!");
        }catch (Exception e){
            throw new CanTellUserException("服务器异常!");
        }

    }

    /**
     * 根据 用户名， 密码 查找 对应的数据。
     * @param username
     * @param pwd
     * @return
     */
    @Override
    public User findUser(String username, String pwd) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", username).eq("password", pwd));

        return user;
    }

    /**
     *   获取经历
     * @return
     */
    @Override
    public List<Experience> initExperience() {
        List<Experience> expList = experienceMapper.selectList(new QueryWrapper<Experience>().orderByDesc("start_time"));
        List<Experience> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(expList)){
            expList.stream().forEach(exp ->{
                String startTime = DateUtils.formatStringByParrtern(exp.getStartTime(), "yyyy年MM月dd日");
                String endTime= DateUtils.formatStringByParrtern(exp.getEndTime(), "yyyy年MM月dd日");
                exp.setPeriod(startTime + "<--->" + endTime);
                List<String> strList = new ArrayList<>();
                if (exp.getJob().indexOf("|") != -1) {
                    String[] split = exp.getJob().split("\\|");
                    if (split.length > 0) {
                        for (String s : split) {
                            strList.add(s);
                        }
                    }
                }else {
                    strList.add(exp.getJob());

                }
                exp.setJobList(strList);
                list.add(exp);
            });
        }

        return list;
    }

    /**
     * 更新用户。
     * @param user
     */
    @Override
    public User update(User user) {
        if (user.getId() != null) {
            userMapper.updateById(user);
        }else {
            userMapper.insert(user);
        }
        return user;
    }
}
